package com.dingreading.cloud.admin.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.admin.dto.LessonAndRequestDto;
import com.dingreading.cloud.admin.dto.SubjectLessonDto;
import com.dingreading.cloud.admin.dto.SubjectLessonListDto;
import com.dingreading.cloud.admin.entity.RequestLog2025;
import com.dingreading.cloud.admin.entity.SubjectLesson;
import com.dingreading.cloud.admin.entity.SubjectLessonLog;
import com.dingreading.cloud.admin.entity.table.SubjectLessonTableDef;
import com.dingreading.cloud.admin.mapper.SubjectLessonMapper;
import com.dingreading.cloud.admin.service.RequestLog2025Service;
import com.dingreading.cloud.admin.service.SubjectLessonLogService;
import com.dingreading.cloud.admin.service.SubjectLessonService;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.NepUtil;
import com.dingreading.cloud.common.util.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 服务层实现。
 *
 * @author Administrator
 * @since 2023-11-22
 */
@Service
public class SubjectLessonServiceImpl extends BaseServiceImpl<SubjectLessonMapper, SubjectLesson, SubjectLessonTableDef> implements SubjectLessonService {

    @Override
    protected SubjectLessonTableDef getTable() {
        return SubjectLessonTableDef.subjectLesson;
    }

    @Resource
    private SubjectLessonLogService subjectLessonLogService;
    @Resource
    private RequestLog2025Service requestLog2025Service;

    @Override
    public Page<SubjectLessonListDto> pageList(PageUtil pageUtil, Long subjectMainId, Long subjectId) {
        QueryCondition condition = QueryCondition.createEmpty();
        if (subjectMainId != null)
            condition.and(table.subjectMainId.eq(subjectMainId));
        if (subjectId != null)
            condition.and(table.subjectId.eq(subjectId));

        QueryWrapper wrapper = QueryWrapper.create()
                .where(condition)
                .orderBy(table.lessonOrder.asc(), table.id.asc());

        return getMapper().paginateWithRelationsAs(Page.of(pageUtil.getPage(), pageUtil.getRows()), wrapper, SubjectLessonListDto.class);
    }

    @Override
    public void updateEnabled(Long id, Integer enabled) {
        UpdateChain.of(SubjectLesson.class)
                .set(table.enabled, enabled)
                .where(table.id.eq(id))
                .update();
    }


    @Override
    public int getMaxLessonOrder(Long subjectMainId, Long subjectId) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.subjectMainId.eq(subjectMainId))
                .and(table.subjectId.eq(subjectId));

        QueryWrapper wrapper = QueryWrapper.create()
                .select(QueryMethods.max(table.lessonOrder))
                .from(table)
                .where(condition);

        Integer integer = getMapper().selectObjectByQueryAs(wrapper, Integer.class);
        return NepUtil.nullToZero(integer);
    }

    @Override
    public R<Object> updateBookInfo(String staffUid, String staffName, String uid, String bookIsbn, String bookPress, String bookImg) {
        boolean update = UpdateChain.of(SubjectLesson.class)
                .set(table.bookIsbn, bookIsbn)
                .set(table.bookPress, bookPress)
                .set(table.bookImg, bookImg)
                .set(table.lastStaffUid, staffUid)
                .set(table.lastStaffName, staffName)
                .where(table.uid.eq(uid))
                .update();
        if (!update)
            return R.fail();
        return R.ok();
    }

    @Override
    public SubjectLessonDto dtoByUid(String uid) {
        QueryWrapper wrapper = QueryWrapper.create()
                .where(table.uid.eq(uid));
        return getMapper().selectOneByQueryAs(wrapper, SubjectLessonDto.class);
    }

    @Override
    public SubjectLessonDto dtoRelationById(Long id) {
        QueryWrapper wrapper = QueryWrapper.create()
                .where(table.id.eq(id));
        return getMapper().selectOneWithRelationsByQueryAs(wrapper, SubjectLessonDto.class);
    }

    @Override
    public R<Object> addRecord(String beginDate, String endDate) {
        if (StringUtils.isBlank(beginDate)) return R.fail("请选择开始日期");
        if (StringUtils.isBlank(endDate)) return R.fail("请选择结束日期");

        // 1. 一次性查询出所有时间范围内的日志
        List<RequestLog2025> requestLogList = requestLog2025Service.getByDate(beginDate, endDate);
        if (CollectionUtils.isEmpty(requestLogList)) {
            return R.fail("该时间范围内没有数据");
        }

        // 2. 准备一个列表，用于收集所有需要查询的 SubjectLesson ID
        List<Long> subjectLessonIds = new ArrayList<>();
        // 临时存储解析后的DTO，避免二次解析
        List<LessonAndRequestDto> tempRequestDtoList = new ArrayList<>();

        for (RequestLog2025 requestLog : requestLogList) {
            if (StringUtils.isBlank(requestLog.getJsonRequest())) {
                continue; // 跳过无效数据
            }
            try {
                LessonAndRequestDto dto = JSONObject.parseObject(requestLog.getJsonRequest(), LessonAndRequestDto.class);
                if (dto != null && dto.getId() != null) {
                    subjectLessonIds.add(dto.getId());
                    // 补充原始日志中的信息
                    dto.setIp(requestLog.getIp());
                    dto.setAddTime(requestLog.getAddTime());
                    tempRequestDtoList.add(dto);
                }
            } catch (Exception e) {
                System.out.println("解析RequestLog失败" + requestLog.getId() + "" + e);
            }
        }

        if (CollectionUtils.isEmpty(subjectLessonIds)) {
            return R.fail("没有有效的待处理数据");
        }

        // 3. 一次性批量查询所有相关的 SubjectLesson
        QueryCondition condition = QueryCondition.createEmpty()
                .and(table.id.in(subjectLessonIds));
        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.id, table.uid)
                .where(condition);
        List<SubjectLesson> subjectLessonList = getMapper().selectListByQuery(wrapper);
        if (CollectionUtils.isEmpty(subjectLessonList)) {
            return R.fail("未找到任何对应的课程信息");
        }

        // 4. 将查询结果转为 Map<id, uid>，方便快速查找，避免再次遍历
        Map<Long, String> lessonIdToUidMap = subjectLessonList.stream()
                .collect(Collectors.toMap(SubjectLesson::getId, SubjectLesson::getUid, (v1, v2) -> v1)); // (v1, v2) -> v1 防止key重复

        // 5. 构建最终要保存的 SubjectLessonLog 列表
        List<SubjectLessonLog> lessonLogList = new ArrayList<>();
        for (LessonAndRequestDto requestDto : tempRequestDtoList) {
            // 从Map中高效获取 lessonUid
            String lessonUid = lessonIdToUidMap.get(requestDto.getId());
            if (lessonUid != null) {
                SubjectLessonLog lessonLog = new SubjectLessonLog();
                lessonLog.setAddTime(requestDto.getAddTime());
                lessonLog.setCorpUid(requestDto.getCorpUid());
                lessonLog.setStoreUid(requestDto.getStoreUid());
                lessonLog.setStaffUid(requestDto.getStaffUid());
                lessonLog.setStaffName(requestDto.getStaffName());
                lessonLog.setIp(requestDto.getIp());
                lessonLog.setLessonUid(lessonUid);
                lessonLog.setType(1);
                lessonLogList.add(lessonLog);
            }
        }

        // 修复逻辑错误，并进行分批插入
        if (!CollectionUtils.isEmpty(lessonLogList)) {
            // 6. 分批插入，比如每批500条
            subjectLessonLogService.saveBatch(lessonLogList, 500);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("原始数据共多少条", requestLogList.size());
        jsonObject.put("有效处理数据共多少条", tempRequestDtoList.size());
        jsonObject.put("成功保存日志多少条", lessonLogList.size());
        jsonObject.put("date", beginDate + "至" + endDate);
        return R.ok(jsonObject);
    }

    @Override
    public List<SubjectLesson> listBySubjectIdIn(List<Long> subjectIdList) {
        QueryWrapper wrapper = QueryWrapper.create()
                .where(table.subjectId.in(subjectIdList))
                .orderBy(table.subjectId.asc(), table.lessonOrder.asc());
        return getMapper().selectListByQuery(wrapper);
    }

    @Override
    public void copy(Long id, String uid, String name, String htmlUrl, String dataUrl, String teachPlanUrl, Integer xcxStatus) {
        UpdateChain.of(SubjectLesson.class)
                .set(table.uid, uid)
                .set(table.lessonName, name)
                .set(table.htmlUrl, htmlUrl)
                .set(table.dataUrl, dataUrl)
                .set(table.teachPlanUrl, teachPlanUrl)
                .set(table.xcxStatus, xcxStatus)
                .where(table.id.eq(id))
                .update();
    }

}
